home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 198_01 / bind.c < prev    next >
C/C++ Source or Header  |  1990-01-21  |  19KB  |  807 lines

  1. /*    This file is for functions having to do with key bindings,
  2.     descriptions, help commands and startup file.
  3.  
  4.     written 11-feb-86 by Daniel Lawrence
  5.                                 */
  6.  
  7. #include    <stdio.h>
  8. #include    "estruct.h"
  9. #include    "edef.h"
  10. #include    "epath.h"
  11.  
  12. extern int meta(), cex(), unarg(), ctrlg(); /* dummy prefix binding functions */
  13.  
  14. help(f, n)    /* give me some help!!!!
  15.            bring up a fake buffer and read the help file
  16.            into it with view mode            */
  17. {
  18.     register BUFFER *bp;    /* buffer pointer to help */
  19.     char *fname;        /* ptr to file returned by flook() */
  20.  
  21.     /* first check if we are already here */
  22.     bp = bfind("emacs.hlp", FALSE, BFINVS);
  23.  
  24.     if (bp == NULL) {
  25.         fname = flook(pathname[1], FALSE);
  26.         if (fname == NULL) {
  27.             mlwrite("[Help file is not online]");
  28.             return(FALSE);
  29.         }
  30.     }
  31.  
  32.     /* split the current window to make room for the help stuff */
  33.     if (splitwind(FALSE, 1) == FALSE)
  34.             return(FALSE);
  35.     curwp = spltwp; curbp = curwp->w_bufp;
  36.  
  37.     if (bp == NULL) {
  38.         /* and read the stuff in */
  39.         if (getfile(fname, FALSE) == FALSE)
  40.             return(FALSE);
  41.     } else
  42.         swbuffer(bp);
  43.  
  44.     /* make this window in VIEW mode, update all mode lines */
  45.     curbp->b_mode |= MDVIEW;
  46.     curbp->b_flag |= BFINVS;
  47.     upmode();
  48.     return(TRUE);
  49. }
  50.  
  51. deskey(f, n)    /* describe the command for a certain key */
  52.  
  53. {
  54.     register int c;        /* key to describe */
  55.     register char *ptr;    /* string pointer to scan output strings */
  56.     char outseq[NSTRING];    /* output buffer for command sequence */
  57. #if    C86 | DECUSC
  58.     int *getbind();
  59. #else
  60.     int (*getbind())();
  61. #endif
  62.  
  63.     /* prompt the user to type us a key to describe */
  64.     mlwrite(": describe-key ");
  65.  
  66.     /* get the command sequence to describe
  67.        change it to something we can print as well */
  68.     cmdstr(c = getckey(FALSE), &outseq[0]);
  69.  
  70.     /* and dump it out */
  71.     ostring(outseq);
  72.     ostring(" ");
  73.  
  74.     /* find the right ->function */
  75.     if ((ptr = getfname(getbind(c))) == NULL)
  76.         ptr = "Not Bound";
  77.  
  78.     /* output the command sequence */
  79.     ostring(ptr);
  80. }
  81.  
  82. /* bindtokey:    add a new key to the key binding table        */
  83.  
  84. bindtokey(f, n)
  85.  
  86. int f, n;    /* command arguments [IGNORED] */
  87.  
  88. {
  89.     register unsigned int c;/* command key to bind */
  90.     register (*kfunc)();    /* ptr to the requested function to bind to */
  91.     register KEYTAB *ktp;    /* pointer into the command table */
  92.     register int found;    /* matched command flag */
  93.     char outseq[80];    /* output buffer for keystroke sequence */
  94.     int (*getname())();
  95. #if    C86 | DECUSC
  96.     int (*fmeta)(), (*fcex)(), (*funarg)(), (*fctrlg)();
  97.  
  98.     fmeta = meta; fcex = cex; funarg = unarg; fctrlg = ctrlg;
  99. #else
  100. #define    fmeta    meta
  101. #define    fcex    cex
  102. #define    funarg    unarg
  103. #define    fctrlg    ctrlg
  104. #endif
  105.  
  106.  
  107.     /* prompt the user to type in a key to bind */
  108.     mlwrite(": bind-to-key ");
  109.  
  110.     /* get the function name to bind it to */
  111.     kfunc = getname();
  112.     if (kfunc == NULL) {
  113.         mlwrite("[No such function]");
  114.         return(FALSE);
  115.     }
  116.     ostring(" ");
  117.  
  118.     /* get the command sequence to bind */
  119.     TTflush();
  120.     c = getckey((kfunc == fmeta) || (kfunc == fcex) ||
  121.                 (kfunc == funarg) || (kfunc == fctrlg));
  122.  
  123.     /* change it to something we can print as well */
  124.     cmdstr((int) c, &outseq[0]);
  125.  
  126.     /* and dump it out */
  127.     ostring(outseq);
  128.  
  129.     /* if the function is a prefix key */
  130.     if (kfunc == fmeta || kfunc == fcex ||
  131.         kfunc == funarg || kfunc == fctrlg) {
  132.         /* search for an existing binding for the prefix key */
  133.         ktp = &keytab[0];
  134. #if DECEDT
  135.         if (kfunc == funarg || kfunc == fctrlg)
  136. #endif
  137.         while (ktp->k_fp != NULL) {
  138.             if (ktp->k_fp == kfunc)
  139.                 chunbind(ktp->k_code);
  140.             ++ktp;
  141.         }
  142.  
  143.         /* reset the appropriate global prefix variable */
  144.         if (kfunc == fmeta) metac = c;
  145.         if (kfunc == fcex) ctlxc = c;
  146.         if (kfunc == funarg) reptc = c;
  147.         if (kfunc == fctrlg) abortc = c;
  148.     }
  149.  
  150.     /* search the table to see if it exists */
  151.     ktp = &keytab[0];
  152.     found = FALSE;
  153.     while (ktp->k_fp != NULL) {
  154.         if (ktp->k_code == c) {
  155.             found = TRUE;
  156.             break;
  157.         }
  158.         ++ktp;
  159.     }
  160.  
  161.     if (found) {    /* it exists, just change it then */
  162.         if (ktp->k_fp == fmeta) metac = 0;
  163.         if (ktp->k_fp == fcex) ctlxc = 0;
  164.         if (ktp->k_fp == funarg) reptc = 0;
  165.         if (ktp->k_fp == fctrlg) abortc = 0;
  166.  
  167.         ktp->k_fp = kfunc;
  168.         if (c > 0 && c < NFBIND) fkeytab[c] = kfunc;
  169.         else if (c == (FUNC|'C')) ffuncc = kfunc;
  170.         fkeylast.k_code = c;
  171.         fkeylast.k_fp = kfunc;
  172.     } else {    /* otherwise we need to add it to the end */
  173.         /* if we run out of binding room, bitch */
  174.         if (ktp >= &keytab[NBINDS]) {
  175.             mlwrite("Binding table FULL!");
  176.             return(FALSE);
  177.         }
  178.  
  179.         ktp->k_code = c;    /* add keycode */
  180.         ktp->k_fp = kfunc;    /* and the function pointer */
  181.         ++ktp;            /* and make sure the next is null */
  182.         ktp->k_code = 0;
  183.         ktp->k_fp = NULL;
  184.         if (c > 0 && c < NFBIND) fkeytab[c] = kfunc;
  185.         else if (c == (FUNC|'C')) ffuncc = kfunc;
  186.         fkeylast.k_code = c;
  187.         fkeylast.k_fp = kfunc;
  188.     }
  189.     return(TRUE);
  190. }
  191.  
  192. /* unbindkey:    delete a key from the key binding table    */
  193.  
  194. unbindkey(f, n)
  195.  
  196. int f, n;    /* command arguments [IGNORED] */
  197.  
  198. {
  199.     register int c;        /* command key to unbind */
  200.     char outseq[80];    /* output buffer for keystroke sequence */
  201.  
  202.     /* prompt the user to type in a key to unbind */
  203.     mlwrite(": unbind-key ");
  204.  
  205.     /* get the command sequence to unbind */
  206.     c = getckey(FALSE);        /* get a command sequence */
  207.  
  208.     /* change it to something we can print as well */
  209.     cmdstr(c, &outseq[0]);
  210.  
  211.     /* and dump it out */
  212.     ostring(outseq);
  213.  
  214.     /* if it isn't bound, bitch */
  215.     if (chunbind(c) == FALSE) {
  216.         mlwrite("[Key not bound]");
  217.         return(FALSE);
  218.     }
  219.     return(TRUE);
  220. }
  221.  
  222. chunbind(c)
  223.  
  224. int c;        /* command key to unbind */
  225.  
  226. {
  227.     register KEYTAB *ktp;    /* pointer into the command table */
  228.     register KEYTAB *sktp;    /* saved pointer into the command table */
  229.     register int found;    /* matched command flag */
  230.  
  231.     /* search the table to see if the key exists */
  232.     ktp = &keytab[0];
  233.     found = FALSE;
  234.     while (ktp->k_fp != NULL) {
  235.         if (ktp->k_code == c) {
  236.             found = TRUE;
  237.             break;
  238.         }
  239.         ++ktp;
  240.     }
  241.  
  242.     /* if it isn't bound, bitch */
  243.     if (!found)
  244.         return(FALSE);
  245.  
  246.     /* save the pointer and scan to the end of the table */
  247.     sktp = ktp;
  248.     while (ktp->k_fp != NULL)
  249.         ++ktp;
  250.     --ktp;        /* backup to the last legit entry */
  251.  
  252.     /* copy the last entry to the current one */
  253.     sktp->k_code = ktp->k_code;
  254.     sktp->k_fp   = ktp->k_fp;
  255.  
  256.     /* null out the last one */
  257.     ktp->k_code = 0;
  258.     ktp->k_fp = NULL;
  259.  
  260.     /* clear in fast lookup area */
  261.     if (c > 0 && c < NFBIND) fkeytab[c] = NULL;
  262.     else if (c == (FUNC|'C')) ffuncc = NULL;
  263.     fkeylast.k_code = keytab[0].k_code;
  264.     fkeylast.k_fp = keytab[0].k_fp;
  265.  
  266.     return(TRUE);
  267. }
  268.  
  269. desbind(f, n)    /* describe bindings
  270.            bring up a fake buffer and list the key bindings
  271.            into it with view mode            */
  272.  
  273. #if    APROP
  274. {
  275.     buildlist(TRUE, "");
  276. }
  277.  
  278. apro(f, n)    /* Apropos (List functions that match a substring) */
  279.  
  280. {
  281.     char mstring[NSTRING];    /* string to match cmd names to */
  282.     int status;        /* status return */
  283.  
  284.     status = mlreply("Apropos string: ", mstring, NSTRING - 1);
  285.     if (status != TRUE)
  286.         return(status);
  287.  
  288.     return(buildlist(FALSE, mstring));
  289. }
  290.  
  291. buildlist(type, mstring)  /* build a binding list (limited or full) */
  292.  
  293. int type;    /* true = full list,   false = partial list */
  294. char *mstring;    /* match string if a partial list */
  295.  
  296. #endif
  297. {
  298. #if    ST520 & LATTICE
  299. #define    register        
  300. #endif
  301.     register WINDOW *wp;    /* scanning pointer to windows */
  302.     register KEYTAB *ktp;    /* pointer into the command table */
  303.     register NBIND *nptr;    /* pointer into the name binding table */
  304.     register BUFFER *bp;    /* buffer to put binding list into */
  305.     int cpos;        /* current position to use in outseq */
  306.     char outseq[80];    /* output buffer for keystroke sequence */
  307.  
  308.     /* split the current window to make room for the binding list */
  309.     if (splitwind(FALSE, 1) == FALSE)
  310.             return(FALSE);
  311.     curwp = spltwp; curbp = curwp->w_bufp;
  312.  
  313.     /* and get a buffer for it */
  314.     bp = bfind("Binding list", TRUE, 0);
  315.     if (bp == NULL || bclear(bp) == FALSE) {
  316.         mlwrite("Can not display binding list");
  317.         return(FALSE);
  318.     }
  319.  
  320.     /* let us know this is in progress */
  321.     mlwrite("[Building binding list]");
  322.  
  323.     /* disconect the current buffer *